package org.jeecg.modules.monitoring.j_monitoring.gatewayData;

import com.alibaba.fastjson.JSONArray;
import com.xkcoding.http.util.StringUtil;
import org.apache.commons.lang.math.NumberUtils;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.config.sign.util.NoSslHttpUtils;
import org.jeecg.config.vo.HttpResult;
import org.jeecg.modules.monitoring.j_monitoring.entity.NetworkInterfaceLog;
import org.jeecg.modules.monitoring.j_monitoring.entity.fdnEntity.*;
import org.jeecg.modules.monitoring.j_monitoring.mapper.NetworkInterfaceLogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;
import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 网络资源获取数据
 */
@Component
public class NetworkResources {
    @Autowired
    private Environment env;

    @Resource
    private NetworkInterfaceLogMapper logMapper;

    private String params =
            "HuaweiMemoryMonitor," +  //内存
                    "PingMonitor," +          //响应时间
                    "SystemUptime," +         //系统最后更新时间
                    "HuaweiCPUMonitor," +     //cpu
                    "HuaweiEntFan," +     //风扇
                    "HuaweiEntPowerSupply," +     //电源
                    "IPInterface";            //接口

    private String deviceMonitors = "/ng/integration/deviceMonitors";

    private String jsonFilePath = "D:\\jsonFile\\network.txt";

    public String getRequestData(String fdn){

        String url = env.getProperty("gatewaySystem.url");

        String header = env.getProperty("gatewaySystem.header");

        String queryUrl = url + deviceMonitors + "?types=" + params + "&device_fdns=" + fdn;

        String json = "";
        if (!"prod".equals(env.getProperty("spring.profiles.active"))) {
            File jsonFile = new File(jsonFilePath);
//            通过上面那个方法获取json文件的内容
            json = CommonUtils.getStr(jsonFile);

        } else {
            HttpResult res = NoSslHttpUtils.noSslGet(queryUrl, header);
            json = res.getBody();
        }
        return json;
    }

    public NetworkResultData getData(String fdn) {

        NetworkResultData resultData = new NetworkResultData();

        String json = this.getRequestData(fdn);

        try {
            List<DevicesMonitors> monitorsList = JSONArray.parseArray(json, DevicesMonitors.class);
            DevicesMonitors monitors = monitorsList.get(0);

            List<Fan> fanList = new ArrayList<>();
            List<Power> powerList = new ArrayList<>();
            for (DevicesCounters counters : monitors.getMonitors()) {

                if ("HuaweiMemoryMonitor".equals(counters.getType()) && counters.getCounters().size() > 0) {

                    //内存
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Memory Utilization".equals(devicesData.getName())) {
                            resultData.setMemoryOccupy(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }
                }

                if ("PingMonitor".equals(counters.getType()) && counters.getCounters().size() > 0) {

                    //响应时间
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Response Time".equals(devicesData.getName())) {
                            resultData.setResponseTime(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }
                }

                if ("HuaweiCPUMonitor".equals(counters.getType()) && counters.getCounters().size() > 0) {

                    //cpu
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("CPU Utilization".equals(devicesData.getName())) {
                            resultData.setCpu(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }
                }

                if ("SystemUptime".equals(counters.getType()) && counters.getCounters().size() > 0) {

                    //上次启动时间
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("UptimeDays".equals(devicesData.getName())) {
                            resultData.setLastTime(devicesData.getValue()+"天");
                        }
                    }
                }

                if ("HuaweiEntFan".equals(counters.getType()) && counters.getCounters().size() > 0) {
                    Fan fan = new Fan();
                    //响应时间
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Status".equals(devicesData.getName())) {
                            fan.setStatus(devicesData.getValue());
                        }
                        if ("Speed".equals(devicesData.getName())) {
                            fan.setSpeed(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }
                    fan.setName(counters.getName());
                    fanList.add(fan);
                }

                if ("HuaweiEntPowerSupply".equals(counters.getType()) && counters.getCounters().size() > 0) {
                    Power power = new Power();
                    //响应时间
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Status".equals(devicesData.getName())) {
                            power.setStatus(devicesData.getValue());
                        }
                    }
                    power.setName(counters.getName());
                    powerList.add(power);
                }

            }
            resultData.setFanList(fanList);
            resultData.setPowerList(powerList);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return resultData;
    }

    public NetworkEquipmentResult showIpInterface(String fdn) {
        NetworkEquipmentResult result = new NetworkEquipmentResult();
        String json = getRequestData(fdn);

        try {

            List<DevicesMonitors> monitorsList = JSONArray.parseArray(json, DevicesMonitors.class);
            DevicesMonitors monitors = monitorsList.get(0);

            //判断是否为多台交换机集合机
            Boolean isCollect = this.getIsCollect(monitors);

            if (isCollect){
                return this.getCollectResult(monitors);
            }else {
                return this.getNormalResult(monitors);
            }

        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return result;
    }


    public NetworkEquipmentResult getCollectResult(DevicesMonitors monitors){
        NetworkEquipmentResult result = new NetworkEquipmentResult();
        Map<String, List<IPInterface>> objectMap = new HashMap<>();
        try {

            result.setCollect(true);

            int count = 0;
            int unused = 0;

            for (DevicesCounters counters : monitors.getMonitors()) {
                IPInterface ipInterface = new IPInterface();
                if (!counters.getEnabled()) {
                    unused++;
                }
                if ("IPInterface".equals(counters.getType())) {
                    count++;
                    String[] strs = counters.getName().split("/");
                    if (strs.length <= 1) {
                        unused++;
                        continue;
                    }

                    if(strs[0].contains("Sip") || strs[0].equals("MEth0")){
                        continue;
                    }

                    List<IPInterface> ipInterfaceList = new ArrayList<>();


                    if (objectMap.containsKey(strs[0].substring(strs[0].length() - 1))) {
                        ipInterfaceList = objectMap.get(strs[0].substring(strs[0].length() - 1));
                    } else {
                        ipInterfaceList = new ArrayList<>();
                    }


                    ipInterface.setPosition(new Integer(strs[strs.length - 1])+1);
                    ipInterface.setName(counters.getName());
                    ipInterface.setStatus("0");
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Operation Status".equals(devicesData.getName())) {
                            ipInterface.setStatus(devicesData.getValue());
                        }
                        if ("Input Rate".equals(devicesData.getName())) {
                            ipInterface.setUp(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                        if ("Output Rate".equals(devicesData.getName())) {
                            ipInterface.setDown(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }

                    ipInterfaceList.add(ipInterface);
                    Collections.sort(ipInterfaceList);
                    objectMap.put(strs[0].substring(strs[0].length() - 1), ipInterfaceList);
                }
            }


            List<List<List<IPInterface>>> resMapList = new ArrayList<>();

            for (Map.Entry<String, List<IPInterface>> entry : objectMap.entrySet()) {
                List<List<IPInterface>> resList = new ArrayList<>();
                TreeMap<Integer,List<IPInterface>> ipMap2 = new TreeMap<>();
                for (IPInterface ipInterface : entry.getValue()){
                    String[] strs = ipInterface.getName().split("/");
                    List<IPInterface> ipInterfaceList = new ArrayList<>();

                    Integer key = new Integer(CommonUtils.extractNumbers(strs[1]));
                    if (ipMap2.containsKey(key)) {
                        ipInterfaceList = ipMap2.get(key);
                    } else {
                        ipInterfaceList = new ArrayList<>();
                    }
                    ipInterfaceList.add(ipInterface);
                    ipMap2.put(key,ipInterfaceList);
                }



                for (Map.Entry<Integer, List<IPInterface>> entry1 : ipMap2.entrySet()) {
                    resList.add(entry1.getValue());
                }
                resMapList.add(resList);
            }


            result.setCount(count);
            result.setUnUsed(unused);
            result.setUsed(count - unused);
            result.setIpInterfaceList(resMapList);
            return result;
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return result;

    }

    public NetworkEquipmentResult getNormalResult(DevicesMonitors monitors){
        NetworkEquipmentResult result = new NetworkEquipmentResult();
        Map<String, List<IPInterface>> objectMap = new HashMap<>();
        try {

            result.setCollect(false);

            int count = 0;
            int unused = 0;

            for (DevicesCounters counters : monitors.getMonitors()) {
                IPInterface ipInterface = new IPInterface();
                if (!counters.getEnabled()) {
                    unused++;
                }
                if ("IPInterface".equals(counters.getType())) {
                    count++;
                    String[] strs = counters.getName().split("/");
                    if (strs.length <= 1) {
                        unused++;
                        continue;
                    }

                    if(strs[0].equals("MEth0")){
                        continue;
                    }

                    List<IPInterface> ipInterfaceList = new ArrayList<>();
                    if (objectMap.containsKey(strs[0])) {
                        ipInterfaceList = objectMap.get(strs[0]);
                    } else {
                        ipInterfaceList = new ArrayList<>();
                    }


                    ipInterface.setPosition(new Integer(strs[strs.length - 1]));
                    ipInterface.setName(counters.getName());
                    ipInterface.setStatus("0");
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Operation Status".equals(devicesData.getName())) {
                            ipInterface.setStatus(devicesData.getValue());
                        }
                        if ("Input Rate".equals(devicesData.getName())) {
                            ipInterface.setUp(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                        if ("Output Rate".equals(devicesData.getName())) {
                            ipInterface.setDown(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }

                    ipInterfaceList.add(ipInterface);
                    Collections.sort(ipInterfaceList);
                    objectMap.put(strs[0], ipInterfaceList);
                }
            }
            List<List<IPInterface>> resList = new ArrayList<>();
            //千兆口换位置
            List<List<IPInterface>> xResultList = new ArrayList<>();

            List<Map<String,List<IPInterface>>> resMapList = new ArrayList<>();

            TreeMap<Integer, List<IPInterface>> resMap = new TreeMap<>();
            TreeMap<Integer, List<IPInterface>> xResultMap = new TreeMap<>();

            for (String key : objectMap.keySet()) {

                List<IPInterface> value = objectMap.get(key);

                Integer keyNum = new Integer(CommonUtils.extractNumbers(key));

                if (value.size() <=2){
                    xResultMap.put(keyNum,value);
                }else{
                    resMap.put(keyNum,value);
                }
            }

            for (Map.Entry<Integer, List<IPInterface>> entry : resMap.entrySet()) {
                Map<String,List<IPInterface>> ipMap = new HashMap<>();
                ipMap.put("res",entry.getValue());
                ipMap.put("xRes",xResultMap.get(entry.getKey()) == null ? new ArrayList<>() : xResultMap.get(entry.getKey()));
                resMapList.add(ipMap);
            }


            result.setCount(count);
            result.setUnUsed(unused);
            result.setUsed(count - unused);
            result.setIpInterfaceList(resMapList);
            return result;
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return result;
    }

    private String Scale(String math){

        if (StringUtil.isEmpty(math)){
            return "";
        }
        try {
            BigDecimal mData = new BigDecimal(math).setScale(2, BigDecimal.ROUND_HALF_UP);
            return mData.toString();
        }catch (Exception e){
            e.printStackTrace();
            return "";
        }
    }

    public List<IPInterface> getIpInterfaceList(String fdn) {

        Map<String, List<IPInterface>> objectMap = new HashMap<>();

        String json = this.getRequestData(fdn);

        try {

            List<DevicesMonitors> monitorsList = JSONArray.parseArray(json, DevicesMonitors.class);
            DevicesMonitors monitors = monitorsList.get(0);

            for (DevicesCounters counters : monitors.getMonitors()) {
                if ("IPInterface".equals(counters.getType()) && counters.getCounters().size() > 0) {
                    String[] strs = counters.getName().split("/");
                    if (strs.length <= 1) {
                        continue;
                    }
                    List<IPInterface> ipInterfaceList = new ArrayList<>();
                    if (objectMap.containsKey(strs[0])) {
                        ipInterfaceList = objectMap.get(strs[0]);
                    } else {
                        ipInterfaceList = new ArrayList<>();
                    }
                    IPInterface ipInterface = new IPInterface();

                    ipInterface.setPosition(new Integer(strs[strs.length - 1]));
                    ipInterface.setName(counters.getName());
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Operation Status".equals(devicesData.getName())) {
                            ipInterface.setStatus(devicesData.getValue());
                        }
                        if ("Operation Status".equals(devicesData.getName())) {
                            ipInterface.setStatus(devicesData.getValue());
                        }
                        if ("Total Input Traffic".equals(devicesData.getName())) {
                            ipInterface.setUp(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                        if ("Total Output Traffic".equals(devicesData.getName())) {
                            ipInterface.setDown(this.Scale(devicesData.getValue())+ devicesData.getUnit());
                        }
                    }


                    ipInterfaceList.add(ipInterface);
                    Collections.sort(ipInterfaceList);
                    objectMap.put(strs[0], ipInterfaceList);

                }
            }
            List<IPInterface> resList = new ArrayList<>();

            for (String key : objectMap.keySet()) {
                List<IPInterface> value = objectMap.get(key);
                for (IPInterface ipInterface : value) {
                    resList.add(ipInterface);
                }

            }

            return resList;
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        return new ArrayList<>();
    }

    /**
     * 记录网络设备接口参数
     */
    public void syncIpInterface(String fdn) {

        String url = env.getProperty("gatewaySystem.url");

        String header = env.getProperty("gatewaySystem.header");

        String queryUrl = url + deviceMonitors + "?types=IPInterface&device_fdns=" + fdn;
        HttpResult res = NoSslHttpUtils.noSslGet(queryUrl, header);
        String json = res.getBody();
//        File jsonFile = new File(jsonFilePath);
//        //通过上面那个方法获取json文件的内容
//        String json = CommonUtils.getStr(jsonFile);


        try {
            List<DevicesMonitors> monitorsList = JSONArray.parseArray(json, DevicesMonitors.class);
            DevicesMonitors monitors = monitorsList.get(0);
            List<NetworkInterfaceLog> insertList = new ArrayList<>();
            int scale = 3;
            BigDecimal rate = new BigDecimal("1024");
            //数据折算--除1024
            for (DevicesCounters counters : monitors.getMonitors()) {
                if (!counters.getEnabled()) {
                    continue;
                }
                if ("IPInterface".equals(counters.getType()) && counters.getCounters().size() > 0) {

                    NetworkInterfaceLog log = new NetworkInterfaceLog();

                    log.setFdn(fdn);
                    log.setName(counters.getName());
                    log.setCreateTime(new Date());
                    for (DevicesData devicesData : counters.getCounters()) {
                        if ("Operation Status".equals(devicesData.getName()) && !devicesData.getValue().equals("1")) {
                            continue;
                        }
                        if ("Total Input Traffic".equals(devicesData.getName())) {
                            log.setTotalInputTraffice(new BigDecimal(devicesData.getValue()).divide(rate,scale, RoundingMode.HALF_UP));
                        }
                        if ("Total Output Traffic".equals(devicesData.getName())) {
                            log.setTotalOutTraffice(new BigDecimal(devicesData.getValue()).divide(rate,scale, RoundingMode.HALF_UP));
                        }
                        if ("In Unicast Packet Rate".equals(devicesData.getName())) {
                            log.setInUnicastPacketRate(new BigDecimal(devicesData.getValue()));
                        }
                        if ("Out Unicast Packet Rate".equals(devicesData.getName())) {
                            log.setOutUnicastPacketRate(new BigDecimal(devicesData.getValue()));
                        }
                        if ("Input Rate".equals(devicesData.getName())) {
                            log.setInputRate(new BigDecimal(devicesData.getValue()).divide(rate,scale, RoundingMode.HALF_UP));
                        }
                        if ("Output Rate".equals(devicesData.getName())) {
                            log.setOutputRate(new BigDecimal(devicesData.getValue()).divide(rate,scale, RoundingMode.HALF_UP));
                        }
                        if ("In Errors".equals(devicesData.getName())) {
                            log.setInError(Double.valueOf(devicesData.getValue()).intValue());
                        }
                        if ("Out Errors".equals(devicesData.getName())) {
                            log.setOutError(Double.valueOf(devicesData.getValue()).intValue());
                        }
                        if ("In Discards".equals(devicesData.getName())) {
                            log.setInDiscards(Double.valueOf(devicesData.getValue()).intValue());
                        }
                        if ("Out Discards".equals(devicesData.getName())) {

                            log.setOutDiscards(Double.valueOf(devicesData.getValue()).intValue());
                        }
                    }
                    if (log.getInputRate() != null) {
                        log.setId(UUID.randomUUID().toString().replace("-", ""));
                        insertList.add(log);
                    }


                }

            }
            if (insertList.size()>0){
                logMapper.insertBatch(insertList);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public Boolean getIsCollect(DevicesMonitors monitors){
        for (DevicesCounters counters : monitors.getMonitors()) {

            if ("IPInterface".equals(counters.getType())) {

                String[] strs = counters.getName().split("/");
                if (strs.length >= 4) {
                    return true;
                }

            }
        }
        return false;
    }
}
